{% extends 'base.html' %}

{% block title %}数据可视化 - 区块链交易行为特征分析与可视化系统{% endblock %}

{% block extra_css %}
<style>
    .chart-container {
        position: relative;
        height: 350px;
        margin-bottom: 20px;
    }
</style>
{% endblock %}

{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
    <h1 class="h2"><i class="fas fa-chart-bar me-2"></i>数据可视化</h1>
</div>

<!-- 加载提示 -->
<div id="loading" class="text-center py-5">
    <div class="spinner-border text-primary" role="status">
        <span class="visually-hidden">加载中...</span>
    </div>
    <p class="mt-2">正在加载可视化数据，请稍候...</p>
</div>

<!-- 可视化内容 -->
<div id="visualization-content" style="display: none;">
    <!-- 用户近期交易金额趋势 -->
    <div class="card mb-4">
        <div class="card-header bg-primary text-white">
            <h5 class="mb-0"><i class="fas fa-chart-line me-2"></i>近期交易金额趋势</h5>
        </div>
        <div class="card-body">
            <div class="chart-container">
                <canvas id="transactionTrendChart"></canvas>
            </div>
        </div>
    </div>

    <div class="row">
        <!-- 用户交易次数占比 -->
        <div class="col-md-6 mb-4">
            <div class="card h-100">
                <div class="card-header bg-success text-white">
                    <h5 class="mb-0"><i class="fas fa-chart-pie me-2"></i>用户交易次数占比</h5>
                </div>
                <div class="card-body">
                    <div class="chart-container">
                        <canvas id="addressDistributionChart"></canvas>
                    </div>
                </div>
            </div>
        </div>

        <!-- 交易金额分布 -->
        <div class="col-md-6 mb-4">
            <div class="card h-100">
                <div class="card-header bg-info text-white">
                    <h5 class="mb-0"><i class="fas fa-chart-bar me-2"></i>交易金额分布</h5>
                </div>
                <div class="card-body">
                    <div class="chart-container">
                        <canvas id="valueDistributionChart"></canvas>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 数据分析说明 -->
    <div class="card mb-4">
        <div class="card-header bg-warning text-dark">
            <h5 class="mb-0"><i class="fas fa-info-circle me-2"></i>数据分析说明</h5>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-md-4 mb-3">
                    <h5><i class="fas fa-chart-line text-primary me-2"></i>近期交易金额趋势</h5>
                    <p>展示最近30天的每日交易总金额变化趋势，帮助您了解交易活跃度的时间分布特征。</p>
                </div>
                <div class="col-md-4 mb-3">
                    <h5><i class="fas fa-chart-pie text-success me-2"></i>用户交易次数占比</h5>
                    <p>展示交易次数最多的前10个地址及其占比，帮助您识别最活跃的交易参与者。</p>
                </div>
                <div class="col-md-4 mb-3">
                    <h5><i class="fas fa-chart-bar text-info me-2"></i>交易金额分布</h5>
                    <p>展示不同金额范围的交易数量分布，帮助您了解交易金额的集中趋势和离散程度。</p>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 错误提示 -->
<div id="error-message" class="alert alert-danger" style="display: none;">
    <i class="fas fa-exclamation-triangle me-2"></i>
    <span id="error-text">加载数据时发生错误</span>
</div>
{% endblock %}

{% block extra_js %}
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // 加载可视化数据
        loadVisualizationData();
    });

    function loadVisualizationData() {
        fetch('{{ url_for("visualization_data") }}')
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络响应异常');
                }
                return response.json();
            })
            .then(data => {
                // 隐藏加载提示，显示可视化内容
                document.getElementById('loading').style.display = 'none';
                document.getElementById('visualization-content').style.display = 'block';
                
                // 渲染各个图表
                renderTransactionTrendChart(data.daily_values);
                renderAddressDistributionChart(data.address_distribution);
                renderValueDistributionChart(data.value_distribution);
            })
            .catch(error => {
                // 显示错误信息
                document.getElementById('loading').style.display = 'none';
                document.getElementById('error-text').textContent = '加载数据时发生错误: ' + error.message;
                document.getElementById('error-message').style.display = 'block';
                console.error('Error:', error);
            });
    }

    function renderTransactionTrendChart(dailyValues) {
        const ctx = document.getElementById('transactionTrendChart').getContext('2d');
        
        // 提取日期和金额数据
        const labels = dailyValues.map(item => item.day);
        const values = dailyValues.map(item => item.value);
        
        new Chart(ctx, {
            type: 'line',
            data: {
                labels: labels,
                datasets: [{
                    label: '每日交易金额',
                    data: values,
                    backgroundColor: 'rgba(54, 162, 235, 0.2)',
                    borderColor: 'rgba(54, 162, 235, 1)',
                    borderWidth: 2,
                    tension: 0.1,
                    fill: true
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true,
                        title: {
                            display: true,
                            text: '交易金额'
                        }
                    },
                    x: {
                        title: {
                            display: true,
                            text: '日期'
                        }
                    }
                },
                plugins: {
                    title: {
                        display: true,
                        text: '近30天每日交易金额趋势'
                    },
                    tooltip: {
                        callbacks: {
                            label: function(context) {
                                return `交易金额: ${context.parsed.y.toFixed(4)}`;
                            }
                        }
                    }
                }
            }
        });
    }

    function renderAddressDistributionChart(addressDistribution) {
        const ctx = document.getElementById('addressDistributionChart').getContext('2d');
        
        // 提取地址和交易次数数据
        const labels = addressDistribution.map(item => {
            // 截断地址以适应图表显示
            return item.address.substring(0, 8) + '...';
        });
        const counts = addressDistribution.map(item => item.count);
        
        // 生成随机颜色
        const backgroundColors = generateRandomColors(labels.length);
        
        new Chart(ctx, {
            type: 'pie',
            data: {
                labels: labels,
                datasets: [{
                    label: '交易次数',
                    data: counts,
                    backgroundColor: backgroundColors,
                    borderColor: 'rgba(255, 255, 255, 0.8)',
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    title: {
                        display: true,
                        text: '前10个活跃地址交易次数占比'
                    },
                    tooltip: {
                        callbacks: {
                            label: function(context) {
                                const label = context.label || '';
                                const value = context.parsed || 0;
                                const total = context.dataset.data.reduce((a, b) => a + b, 0);
                                const percentage = ((value / total) * 100).toFixed(2);
                                return `${label}: ${value} 次 (${percentage}%)`;
                            }
                        }
                    },
                    legend: {
                        position: 'right',
                        labels: {
                            boxWidth: 15
                        }
                    }
                }
            }
        });
    }

    function renderValueDistributionChart(valueDistribution) {
        const ctx = document.getElementById('valueDistributionChart').getContext('2d');
        
        // 提取金额范围和交易数量数据
        const labels = valueDistribution.map(item => item.range);
        const counts = valueDistribution.map(item => item.count);
        
        new Chart(ctx, {
            type: 'bar',
            data: {
                labels: labels,
                datasets: [{
                    label: '交易数量',
                    data: counts,
                    backgroundColor: 'rgba(75, 192, 192, 0.5)',
                    borderColor: 'rgba(75, 192, 192, 1)',
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true,
                        title: {
                            display: true,
                            text: '交易数量'
                        }
                    },
                    x: {
                        title: {
                            display: true,
                            text: '金额范围'
                        }
                    }
                },
                plugins: {
                    title: {
                        display: true,
                        text: '交易金额分布'
                    }
                }
            }
        });
    }

    // 生成随机颜色数组
    function generateRandomColors(count) {
        const colors = [];
        const predefinedColors = [
            'rgba(255, 99, 132, 0.7)',
            'rgba(54, 162, 235, 0.7)',
            'rgba(255, 206, 86, 0.7)',
            'rgba(75, 192, 192, 0.7)',
            'rgba(153, 102, 255, 0.7)',
            'rgba(255, 159, 64, 0.7)',
            'rgba(199, 199, 199, 0.7)',
            'rgba(83, 102, 255, 0.7)',
            'rgba(40, 159, 64, 0.7)',
            'rgba(210, 105, 30, 0.7)'
        ];
        
        for (let i = 0; i < count; i++) {
            if (i < predefinedColors.length) {
                colors.push(predefinedColors[i]);
            } else {
                // 如果预定义颜色不够，生成随机颜色
                const r = Math.floor(Math.random() * 255);
                const g = Math.floor(Math.random() * 255);
                const b = Math.floor(Math.random() * 255);
                colors.push(`rgba(${r}, ${g}, ${b}, 0.7)`);
            }
        }
        
        return colors;
    }
</script>
{% endblock %}